package com.iwhalecloud.bss.kite.cucc.service.scene.bo;

import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.RuleResponseUtils;
import com.iwhalecloud.bss.kite.cucc.event.offer.InitMemOfferEvent;
import com.iwhalecloud.bss.kite.cucc.manager.api.ILocalOperateSceneInstService;
import com.iwhalecloud.bss.kite.cucc.manager.api.ILocalQuerySceneInstService;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.enums.BaseRestrictType;
import com.iwhalecloud.bss.kite.enums.DefaultRestrictType;
import com.iwhalecloud.bss.kite.enums.RestrictTriggerSource;
import com.iwhalecloud.bss.kite.event.attr.AttrRestrictEvent;
import com.iwhalecloud.bss.kite.event.offer.InitMainOfferEvent;
import com.iwhalecloud.bss.kite.event.offer.OfferRestrictDealEvent;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQueryInstTemplateService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.service.rule.RuleUtil;
import com.iwhalecloud.bss.kite.service.rule.impl.RuleTriggerService;
import com.iwhalecloud.bss.kite.service.scene.bo.AbstractOperateSceneOfferInstBO;
import com.iwhalecloud.bss.kite.service.scene.bo.OperateSceneProdInstBO;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import com.ztesoft.bss.rul.core.client.dto.kite.KiteRuleResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class CuccOperateSceneOfferInstBO extends AbstractOperateSceneOfferInstBO {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private ILocalQuerySceneInstService localQuerySceneInstService;

    @Autowired
    private IQueryInstTemplateService queryInstTemplateService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private ILocalOperateSceneInstService localOperateSceneInstService;

    @Autowired
    private RuleTriggerService ruleTriggerService;

    @Autowired
    private OperateSceneProdInstBO operateSceneProdInstBO;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     *  增加一个主套餐
     *
     * @param sceneInstId
     * @param offerId
     * @param custId
     * @param staffId
     * @return
     */
    public KiteOfferInst addMemOfferInst(String sceneInstId, String parOfferInstId, String offerId, String roleId, String custId, String staffId) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        Offer offer = OfferCache.get(offerId);
        if (offer == null) {
            ErrorConsts.OFFER_NOT_EXISTS.throwOut(offerId);
        }

        // 从实例模板缓存中获取实例
        String provinceNbr = sceneInst.getProvinceNbr();
        KiteOfferInst offerInst = queryInstTemplateService.getOfferInst(offerId, provinceNbr);

        // 创建一个主套餐并添加到场景
        if (offerInst == null) {
            offerInst = initKiteOfferInst(offerId, custId, InstType.MEM_OFFER_INST, provinceNbr);
        }
        offerInst.setActionType(ActionType.A);
        operateSceneInstService.addMemOfferInst(sceneInstId, offerInst, parOfferInstId, RelType.OFFER_OBJ_REL_TYPE_120000, ActionType.A);

        // 触发初始化套餐事件
        InitMemOfferEvent initMemOfferEvent = new InitMemOfferEvent(this, custId, staffId);
        initMemOfferEvent.setOfferId(offerId);
        initMemOfferEvent.setParentInstId(offerInst.getOfferInstId());
        initMemOfferEvent.setSceneInstId(sceneInstId);
        applicationContext.publishEvent(initMemOfferEvent);

        // 触发新增产品和新增成员规则
        //RuleUtil.onAddProdRuleAfterByMainOffer(sceneInstId, custId, sceneInst.getServiceOfferId(), offerInst);
        //RuleUtil.onAddMemberRuleAfterByMainOffer(sceneInstId, custId, sceneInst.getServiceOfferId(), offerInst);
        return offerInst;
    }

    /***
     * 退订
     *
     * @param sceneInstId 场景实例ID
     * @param memOfferInstId 主套餐实例ID
     * @param custId 客户标识
     * @param staffId
     * @return
     */
    public Boolean removeMemOfferInst(String sceneInstId, String memOfferInstId, String custId, String staffId) {
        // 1、获取可选包实例是否存在
        KiteOfferInst memOfferInst = querySceneInstService.getOfferInst(custId, memOfferInstId);
        if (Objects.isNull(memOfferInst)) {
            ErrorConsts.DATA_NOT_FOUND.throwOut();
        }

        Offer offer = OfferCache.get(memOfferInst.getOfferId());
        String offerType = offer.getOfferType();

        // 规则埋点 删除销售品 start
        String serviceOfferId = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId).getServiceOfferId();
        RuleCommonParam ruleCommonParam = RuleUtil.getRuleCommonParam(sceneInstId, custId);
        KiteRuleResponse ruleResponse = ruleTriggerService
            .onDelOfferRule(sceneInstId, null, null, null, memOfferInstId, memOfferInst.getOfferId(), offerType, null,
                serviceOfferId, ruleCommonParam);
        RuleResponseUtils.cheackRuleResp(ruleResponse);
        // 规则埋点 删除销售品 end

        // 2、删除销售品实例
        localOperateSceneInstService.deleteMemOfferInst(sceneInstId, memOfferInstId);
        // 退订礼包
        // delGiftOffer(mainOfferInst, custId, sceneInstId);
        List<KiteOfferInst> additionalOfferInsts = new ArrayList<KiteOfferInst>();
        // 3、同时退订套餐下可选包(删除可选包可能需要触发事件处理，此处临时直接删掉可选包)
        if (Objects.equals(memOfferInst.getInstType(), InstType.MAIN_OFFER_INST)) {

            additionalOfferInsts.addAll(Optional
                .ofNullable(querySceneInstService.listAdditionalOfferInstsFromMainOfferInst(custId, memOfferInstId))
                .orElse(Collections.emptyList()));
        }
        else if (Objects.equals(memOfferInst.getInstType(), InstType.MEM_OFFER_INST)) {

            additionalOfferInsts.addAll(Optional
                .ofNullable(localQuerySceneInstService.listAdditionalOfferInstsFromMemOfferInst(custId, memOfferInstId))
                .orElse(Collections.emptyList()));
        }
        else if (Objects.equals(memOfferInst.getInstType(), InstType.PROMOTION_OFFER_INST)) {
            additionalOfferInsts.addAll(Optional.ofNullable(
                querySceneInstService.listAdditionalOfferInstsFromPromotionOfferInst(custId, memOfferInstId))
                .orElse(Collections.emptyList()));

        }
        if (!KiteListUtils.isEmpty(additionalOfferInsts)) {
            additionalOfferInsts.forEach(offerInst -> {
                if (!Objects.equals(offerInst.getActionType().name(), KeyConsts.ACTION_TYPE_D)) {

                    // 规则埋点 删除销售品 start
                    String offerInstId = offerInst.getOfferInstId();
                    String offerIdTemp = offerInst.getOfferId();
                    Offer offerTemp = OfferCache.get(offerIdTemp);
                    String offerTypeTemp = offerTemp.getOfferType();

                    KiteRuleResponse ruleResponseTemp = ruleTriggerService
                        .onDelOfferRule(sceneInstId, null, null, null, offerInstId, offerIdTemp, offerTypeTemp, null,
                            serviceOfferId, ruleCommonParam);
                    RuleResponseUtils.cheackRuleResp(ruleResponseTemp);

                    operateSceneInstService.deleteAdditionalOfferInst(sceneInstId, offerInst.getOfferInstId());
                    //发布销售品约束产品属性事件
                    AttrRestrictEvent attrRestrictEvent = new AttrRestrictEvent(this, AttrRestrictEvent.EVENT_CODE, custId, staffId);
                    attrRestrictEvent.setUpdateFlag(true);
                    attrRestrictEvent.setToDoType(InstType.ADDITIONAL_OFFER_INST);
                    attrRestrictEvent.setBaseRestrictFlag(BaseRestrictType.IS_NEED_NONE);
                    attrRestrictEvent.setDefaultRestrictType(DefaultRestrictType.IS_NEED_NONE);
                    attrRestrictEvent.setToDoInstId(offerInst.getOfferInstId());
                    attrRestrictEvent.setSceneInstId(sceneInstId);
                    applicationContext.publishEvent(attrRestrictEvent);
                }
            });
        }

        // 4.主套餐退订，同时拆机所有成员
        if (Objects.equals(memOfferInst.getInstType(), InstType.MAIN_OFFER_INST)
                || Objects.equals(memOfferInst.getInstType(), InstType.MEM_OFFER_INST)) {
            List<KiteProdInst> prodInsts = querySceneInstService.listProdInstsFromOfferInst(custId, memOfferInstId);
            prodInsts.forEach(prodInst -> {
                //1838966
                //1845199 【生产0107】【top】拆机固话2852333带出手机的拆机和自主版的解体
                List<KiteOfferInst> kiteOfferInsts = querySceneInstService.listMainOfferInstsByProdInstId(custId, prodInst.getProdInstId());
                if (kiteOfferInsts.size() - 1 >= 1) { //如果有多个主套餐的时候不走下面
                    return;
                }
                if (!Objects.equals(prodInst.getActionType().name(), KeyConsts.ACTION_TYPE_D)
                    && KeyConsts.CDMA_PRODUCT_ID.equals(prodInst.getProdId())) {
                    operateSceneProdInstBO.dismantleProdInst(sceneInstId, custId, prodInst.getProdInstId());
                }
            });
        }

        DcPublic dcPublic = DcPublicCache.get("202003230736", "OfferRestrictDealEventFlag");

        if (dcPublic != null && KiteStringUtils.isEqual(KeyConsts.IFTRUE_T, dcPublic.getCodea())) {
            KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
            // 发布销售品集体后其他特殊逻辑//如5G切片流量包退订后退订功能产品等
            OfferRestrictDealEvent offerRestrictDealEvent = new OfferRestrictDealEvent(this,
                OfferRestrictDealEvent.EVENT_CODE, custId, sceneInst.getStaffId());
            offerRestrictDealEvent.setSceneInstId(sceneInstId);
            offerRestrictDealEvent.setOfferInstId(memOfferInstId);
            offerRestrictDealEvent.setTriggerSource(RestrictTriggerSource.OFFER_DEL_SCENE);
            applicationContext.publishEvent(offerRestrictDealEvent);
        }


        return true;
    }
}
